/***************************************************************************
 *   Copyright (C) 2007 by Ziman & Xloverin                                *
 *   ziman@centrum.sk, xloverin@gmail.com                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <QMessageBox>
#include <QPalette>
#include <QtSql/QSqlQuery>
#include <QThread>

#include "query.h"
#include "mainform.h"
#include "core.h"
#include "newquery.h"
#include "query.h"
#include "preferences.h"
#include "richedit.h"
#include "about.h"
#include "editor.h"
#include "passwd.h"

void MainForm::on_actionWrite_a_message_triggered()
{
	Editor *editor = new Editor(0, core, m_mainTerminal);
	editor->show();
	// nechame ho zit a neblokujeme... (zmaze sa sam)
}

void MainForm::displayCharMode(bool charMode)
{
	actionCharacter_mode->setChecked(charMode);
}

void MainForm::on_actionCharacter_mode_toggled(bool charMode)
{
	if (charMode) {
		if (core->readMode() == Core::rmLine) {
			core->setReadMode(Core::rmChar);
		}
	} else {
		if (core->readMode() == Core::rmChar) {
			core->setReadMode(Core::rmLine);
		}
	}
}

void MainForm::on_actionUpdate_nick_list_triggered()
{
	core->nickList().loadFromUrl(core->preferences().general.nickList);
}

void MainForm::on_actionAbout_Spiral_triggered()
{
	About *about = new About(this);
	about->exec();
	delete about;
}

void MainForm::hilightWindow()
{
	m_mainTerminal->activateWindow();
}

void MainForm::onAttachTab()
{
	actionDetach_current->setEnabled(true);
}

void MainForm::on_actionColored_text_editor_triggered()
{
	RichEdit *edit = new RichEdit(this);
	edit->exec();
	delete edit;
}

void MainForm::onAfk(bool afk)
{
	if (afk) {
 		QPalette pal = palette();
		pal.setColor(QPalette::WindowText, Qt::red);
		// pal.setColor(QPalette::WindowText, Qt::yellow);
		statusBar()->setPalette(pal);
		hilightWindow();
	} else {
 		statusBar()->setPalette(palette());
	}
}

void MainForm::onCloseTab(Terminal *terminal)
{
	if (terminal == m_mainTerminal) {
		QMessageBox::critical(0, tr("Close query"), tr("Main terminal cannot be closed."));
		return;
	}

	if (QMessageBox::question(0, tr("Close query"),
							  tr("Do you really want to close the open query?"),
							  QMessageBox::Yes | QMessageBox::No
							 ) == QMessageBox::Yes
	) {

		int tabIndex = tabWidget->indexOf(terminal);
		if (tabIndex != -1) {
			/* Query nie je detasovana */
			tabWidget->removeTab(tabIndex);
		}

		core->deleteQuery(terminal->query());
		terminal->closeTerminal();
	}
}

void MainForm::on_actionClose_current_triggered()
{
	onCloseTab(activeTerminal());
}

void MainForm::on_actionDetach_current_triggered()
{
	if (activeTerminal() == 0) return;
	activeTerminal()->detach(tabWidget->tabText(tabWidget->currentIndex()), tabWidget);
	
	actionDetach_current->setEnabled(activeTerminal() != 0);
}

void MainForm::onLogin(QString nick)
{
	lStatus->setText(tr("Logged in."));
	lNick->setText(nick);
	updateStatusbar();
}

void MainForm::onConnected()
{
	QString msg = tr("Connected.\n\n");
	stripDiacritics(msg);
	m_mainTerminal->write(msg.toAscii());
	actionConnect->setEnabled(false);
	actionDisconnect->setEnabled(true);
	lStatus->setText(tr("Logging in."));
}

void MainForm::onDisconnected()
{
	QString msg = tr("\nDisconnected.\n");
	stripDiacritics(msg);
	m_mainTerminal->write(msg.toAscii());
	actionConnect->setEnabled(true);
	actionDisconnect->setEnabled(false);

	onAfk(false);

	lStatus->setText(tr("Disconnected."));
	lLogin->setText(tr("Not logged in."));
	lIdle->setText(tr("No idle time."));
	lNick->setText(tr("No nick."));
}

class ST : public QThread
{
	public:
		static void msleep(unsigned long msecs)
		{
			QThread::msleep(msecs);
		}
		
		static void qmsleep(unsigned long msecs)
		{
			QApplication::processEvents();
			for (unsigned long time = 0; time < msecs; time += 100)
			{
				msleep(100);
				QApplication::processEvents();
			}
		}
};

void MainForm::on_actionConnect_triggered()
{
	if (core->connected()) return;
	
	Preferences::Prefs prefs = core->preferences();
	
	if (prefs.connection.autoLogin)
	{
		Passwd * passwd = new Passwd(this, prefs.connection.alNick, prefs.connection.alPassword);
		
		passwd->exec();
		
		switch (passwd->login.choice)
		{
			case Passwd::Ok:
			{
				if (passwd->login.remember)
				{
					prefs.connection.alNick = passwd->login.nick;
					prefs.connection.alPassword = passwd->login.passwd;
					core->setPreferences(prefs);
				}
				
				core->connectTalker();
				ST::qmsleep(1000);
				core->getConnection()->write(passwd->login.nick);
				ST::qmsleep(300);
				core->getConnection()->write("\r\n");
				ST::qmsleep(1000);
				core->getConnection()->write(passwd->login.passwd);
				ST::qmsleep(300);
				core->getConnection()->write("\r\n");
			}
			break;
			
			case Passwd::Cancel:
			{
				// do nothing
				return;
			}
			break;
			
			case Passwd::Manual:
			{
				// just let the user connect manually
				core->connectTalker();
			}
			break;
		}
		
		delete passwd;
	}
	else
	{
		// just let the user connect manually
		core->connectTalker();
	}
}

void MainForm::on_actionDisconnect_triggered()
{
	if (!core->connected()) return;
	if (QMessageBox::question(this, tr("Disconnect"),
							  tr("Do you really want to disconnect?"),
							  QMessageBox::Yes | QMessageBox::No
							 ) == QMessageBox::Yes
	) {
		core->disconnectTalker();
	}
}

void MainForm::setTabPosition(QTabWidget::TabPosition tabPos)
{
	tabWidget->setTabPosition(tabPos);
}

void MainForm::on_actionMain_toggled(bool checked)
{
	tbMain->setVisible(checked);
}

void MainForm::on_actionQueries_toggled(bool checked)
{
	tbQueries->setVisible(checked);
}

void MainForm::on_actionMisc_toggled(bool checked)
{
	tbMisc->setVisible(checked);
}

void MainForm::on_tabWidget_currentChanged(QWidget *widget)
{
	actionClose_current->setEnabled(widget != m_mainTerminal);
	setTerminalIcon(qobject_cast<Terminal *>(widget), Query::Inactive);
}

Terminal *MainForm::activeTerminal()
{
	return qobject_cast<Terminal *>(tabWidget->currentWidget());
}

void MainForm::setTerminalIcon(Terminal *terminal, Query::HilightLevel level)
{
	tabWidget->setTabIcon(tabWidget->indexOf(terminal), QIcon(Query::hlIcons[level]));
}

void MainForm::addTerminal(Terminal *terminal, QString title)
{
	tabWidget->addTab(terminal, title);
	setTerminalIcon(terminal, Query::Inactive);
	
	if (core != 0) {
		terminal->setFont(core->preferences().appearance.termFontFace, core->preferences().appearance.termFontSize);
	}

	connect(terminal, SIGNAL(closeTab(Terminal *)), this, SLOT(onCloseTab(Terminal *)));
	connect(terminal, SIGNAL(detachTab()), this, SLOT(on_actionDetach_current_triggered()));
	connect(terminal, SIGNAL(attached()), this, SLOT(onAttachTab()));
}

void MainForm::on_actionPreferences_triggered()
{
	Preferences *dlg = new Preferences(this, core->nickList());
	dlg->setPrefs(core->preferences());
	dlg->exec();

	if (dlg->result() == QDialog::Accepted) {
		core->setPreferences(dlg->prefs());
	}

	delete dlg;
}

void MainForm::on_actionNew_query_triggered()
{
	NewQuery *dlg = new NewQuery(this, core->nickList());
	dlg->exec();

	if (dlg->result() == QDialog::Accepted) {
		core->addQuery(dlg->queryPrefs());
	}

	delete dlg;
}

void MainForm::switchToTerminal(int index)
{
	tabWidget->setCurrentIndex(index);
}

void MainForm::updateStatusbar()
{
	QDateTime now = QDateTime::currentDateTime();
	lTime->setText(now.toString("hh:mm:ss"));
	if (core->loggedIn()) {
		QTime idle = QTime().addSecs(core->lastActTime().secsTo(now));
		lIdle->setText(idle.toString("mm:ss"));

		QTime login = QTime().addSecs(core->loginTime().secsTo(now));
		lLogin->setText(login.toString("hh:mm:ss"));
	}
}

void MainForm::on_actionMain_terminal_triggered() { switchToTerminal(0); }
void MainForm::on_actionTerminal_2_triggered() { switchToTerminal(1); }
void MainForm::on_actionTerminal_3_triggered() { switchToTerminal(2); }
void MainForm::on_actionTerminal_4_triggered() { switchToTerminal(3); }
void MainForm::on_actionTerminal_5_triggered() { switchToTerminal(4); }
void MainForm::on_actionTerminal_6_triggered() { switchToTerminal(5); }
void MainForm::on_actionTerminal_7_triggered() { switchToTerminal(6); }
void MainForm::on_actionTerminal_8_triggered() { switchToTerminal(7); }
void MainForm::on_actionTerminal_9_triggered() { switchToTerminal(8); }
void MainForm::on_actionTerminal_10_triggered() { switchToTerminal(9); }

void MainForm::on_actionDisplay_Gossip_query_triggered()
{
	core->displayGossipQuery();
}

MainForm::MainForm(QWidget* parent, Qt::WFlags fl)
: QMainWindow( parent, fl ), Ui::MainWindow()
{
	setupUi(this);

	core = 0;
	m_mainTerminal = qobject_cast<Terminal *>(tabWidget->widget(0));
	lTime = new QLabel();
	lLogin = new QLabel(tr("Not logged in."));
	lIdle = new QLabel(tr("No idle time."));
	lNick = new QLabel(tr("No nick."));
	lStatus = new QLabel(tr("Disconnected."));
	
	QFont font = lIdle->font();
	font.setBold(true);
	lIdle->setFont(font);

	// Toto by sa malo vytvarat ako posledne, lebo Core uz robi vela bordelu.
	core = new Core(this);

	tbQueries->setVisible(false);
	actionQueries->setChecked(false);

	QStatusBar *sb = this->statusBar();
	sb->addPermanentWidget(lNick);
	sb->addPermanentWidget(lIdle);
	sb->addPermanentWidget(lLogin);
	sb->addPermanentWidget(lTime);
	sb->addPermanentWidget(lStatus);

	sb->setBackgroundRole(QPalette::Window);
	sb->setAutoFillBackground(true);

	statusTimer = new QTimer(this);
	connect(statusTimer, SIGNAL(timeout()), this, SLOT(updateStatusbar()));
	statusTimer->start(1000);
	updateStatusbar();

	connect(actionAbout_Qt_4, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
	connect(core->getConnection(), SIGNAL(connected()), this, SLOT(onConnected()));
	connect(core->getConnection(), SIGNAL(disconnected()), this, SLOT(onDisconnected()));
	connect(core, SIGNAL(login(QString)), this, SLOT(onLogin(QString)));

	on_tabWidget_currentChanged(tabWidget->currentWidget());

	m_mainTerminal->setClosableFromContextMenu(false);
	m_mainTerminal->focusInput();
}

void MainForm::connectIfNecessary()
{
	if (core->preferences().connection.connectAuto) 
	{
		QApplication::processEvents();
		on_actionConnect_triggered();
	}
}

void MainForm::closeEvent(QCloseEvent *evt)
{
	if (core->connected() &&
		QMessageBox::question(this, tr("Exit Spiral"),tr( "Do you really want to quit?"),
		QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
	{
		evt->ignore();
		return;
	}
	
	if (core->getConfig()->get("saveOpenQueriesAsDefaultOnQuit", false)) {
		core->saveCurrentQueriesAsDefault();
	}
	core->savePreferences(core->preferences());

	QMainWindow::closeEvent(evt);
	qApp->quit();
}

Terminal *MainForm::mainTerminal()
{
	return m_mainTerminal;
}

void MainForm::on_actionQuit_triggered()
{
	close();
}

MainForm::~MainForm()
{
	delete core;
}
